package com.weareint.common.beans;

import com.weareint.common.dto.AbstractDTO;
import com.weareint.common.entity.AbstractEntity;
import com.weareint.common.exceptions.SystemRuntimeException;
import com.weareint.common.service.IBasicService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;

/**
 *
 *
 * <pre>
 *      做一个ServiceImpl对象的集合，便于后期获取
 * </pre>
 *
 * @author wangg
 * @date 2021/7/169:32
 */
@Component
public class ServiceBeans implements BeanPostProcessor, ApplicationContextAware {

    private static final String SERVICE_IMPL = "ServiceImpl";

    private final ConcurrentHashMap<
                    String,
                    IBasicService<
                            ? extends AbstractEntity<? extends AbstractDTO>, ? extends AbstractDTO>>
            serviceMap = new ConcurrentHashMap<>();

    private ApplicationContext applicationContext;

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        if (bean instanceof IBasicService) {
            serviceMap.put(
                    beanName,
                    (IBasicService<
                                    ? extends AbstractEntity<? extends AbstractDTO>,
                                    ? extends AbstractDTO>)
                            bean);
        }
        return bean;
    }

    /**
     *
     *
     * <pre>
     *      按实体的名称获取服务实现对象
     * </pre>
     *
     * @param entityNameUncapitalized 实体名，首字母非大写
     * @return 实体服务对象
     */
    public IBasicService<? extends AbstractEntity<? extends AbstractDTO>, ? extends AbstractDTO>
            getService(String entityNameUncapitalized) {
        String key = entityNameUncapitalized + SERVICE_IMPL;
        if (serviceMap.containsKey(key)) {
            return serviceMap.get(key);
        }
        throw new SystemRuntimeException(
                "Not Found Service Impl in Spring Container. beanName = " + key);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
